/**
 * 购物车管理控制器模块
 *
 * 处理购物车相关的HTTP请求
 */

const CartService = require("../services/cart.service");
const logger = require("../utils/logger");
const CustomError = require("../utils/customError");

/**
 * 添加商品到购物车或更新购物车商品数量
 * @param {import('express').Request} req
 * @param {import('express').Response} res
 */
async function addToCart(req, res) {
  const { goodsId, count, blessing } = req.body;
  // 从请求对象中获取userId，如果没有则使用环境变量中的TEST_USER_ID或默认值1（用于测试环境）
  const userId = req.userId || process.env.TEST_USER_ID || 1; // 实际项目中应该从认证中间件获取

  logger.debug(
    `添加商品到购物车, userId: ${userId}, goodsId: ${goodsId}, count: ${count}, blessing: ${blessing}`
  );

  const result = await CartService.addToCart(
    userId,
    parseInt(goodsId),
    parseInt(count),
    blessing
  );

  res.json({
    code: 200,
    message: "添加成功",
    data: result,
  });
}

/**
 * 获取购物车列表
 * @param {import('express').Request} req
 * @param {import('express').Response} res
 */
async function getCartList(req, res) {
  // 从请求对象中获取userId，如果没有则使用环境变量中的TEST_USER_ID或默认值1（用于测试环境）
  const userId = req.userId || process.env.TEST_USER_ID || 1; // 实际项目中应该从认证中间件获取

  logger.debug(`获取购物车列表, userId: ${userId}`);

  const cartList = await CartService.getCartList(userId);

  // 格式化返回数据
  const formattedCartList = cartList.map((item) => {
    const cartItem = item.toJSON ? item.toJSON() : item;
    return {
      id: cartItem.id,
      goodsId: cartItem.goodsId,
      goodsName: cartItem.goods.name,
      price: cartItem.goods.price,
      imageUrl: cartItem.goods.mainImgUrl,
      count: cartItem.quantity,
      checked: cartItem.checked,
      blessing: cartItem.blessing,
      stock: cartItem.goods.stock,
    };
  });

  res.json({
    code: 200,
    message: "获取成功",
    data: formattedCartList,
  });
}

/**
 * 更新购物车中商品的数量或选中状态
 * @param {import('express').Request} req
 * @param {import('express').Response} res
 */
async function updateCartItem(req, res) {
  const { goodsId } = req.params;

  const { quantity, checked, blessing } = req.body;
  // 从请求对象中获取userId，如果没有则使用环境变量中的TEST_USER_ID或默认值1（用于测试环境）
  const userId = req.userId || process.env.TEST_USER_ID || 1; // 实际项目中应该从认证中间件获取

  logger.debug(
    `更新购物车商品, userId: ${userId}, goodsId: ${goodsId}, quantity: ${quantity}, checked: ${checked}, blessing: ${blessing}`
  );

  // 根据请求体中的字段决定更新什么
  if (quantity !== undefined) {
    // 更新数量
    const result = await CartService.addToCart(
      userId,
      parseInt(goodsId),
      parseInt(quantity),
      blessing
    );
    res.json({
      code: 200,
      message: "更新成功",
      data: result,
    });
  } else if (checked !== undefined) {
    // 更新选中状态
    const result = await CartService.checkCart(
      userId,
      parseInt(goodsId),
      parseInt(checked)
    );
    res.json({
      code: 200,
      message: "更新成功",
      data: result,
    });
  } else {
    throw new CustomError(400, "请求参数错误，必须提供quantity或checked字段");
  }
}

/**
 * 实现购物车商品的全选和全不选功能
 * @param {import('express').Request} req
 * @param {import('express').Response} res
 */
async function checkAllCart(req, res) {
  const { checked } = req.body;
  // 从请求对象中获取userId，如果没有则使用环境变量中的TEST_USER_ID或默认值1（用于测试环境）
  const userId = req.userId || process.env.TEST_USER_ID || 1; // 实际项目中应该从认证中间件获取

  logger.debug(`全选/全不选购物车商品, userId: ${userId}, checked: ${checked}`);

  const result = await CartService.checkAllCart(userId, parseInt(checked));

  res.json({
    code: 200,
    message: "更新成功",
    data: result,
  });
}

/**
 * 删除购物车商品
 * @param {import('express').Request} req
 * @param {import('express').Response} res
 */
async function deleteCartItem(req, res) {
  const { goodsId } = req.params;
  // 从请求对象中获取userId，如果没有则使用环境变量中的TEST_USER_ID或默认值1（用于测试环境）
  const userId = req.userId || process.env.TEST_USER_ID || 1; // 实际项目中应该从认证中间件获取

  logger.debug(`删除购物车商品, userId: ${userId}, goodsId: ${goodsId}`);

  const result = await CartService.deleteCartItem(userId, parseInt(goodsId));

  res.json({
    code: 200,
    message: "删除成功",
    data: result,
  });
}

module.exports = {
  addToCart,
  getCartList,
  updateCartItem,
  checkAllCart,
  deleteCartItem,
};
